package cn.oi.klittle.era.widget.photo

import android.content.Context
import android.graphics.*
import android.graphics.drawable.BitmapDrawable
import android.os.Build
import android.util.AttributeSet
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import cn.oi.klittle.era.base.KBaseView
import cn.oi.klittle.era.entity.widget.compat.KRadiusEntity
import cn.oi.klittle.era.utils.KGlideUtils
import cn.oi.klittle.era.utils.KRadiusUtils
import cn.oi.klittle.era.widget.compat.K0Widget
import cn.oi.klittle.era.widget.compat.K7RadiusWidget

/**
 * 普通的ImageView，防止内部图片为空
 * 支持gif图片
 */
class KImageView : ImageView {
    constructor(viewGroup: ViewGroup) : super(viewGroup.context) {
        viewGroup.addView(this)//直接添加进去,省去addView(view)
    }

    constructor(context: Context) : super(context) {}
    constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) {}

    override fun draw(canvas: Canvas?) {
        try {
            //画背景
            drawBg(canvas, this)
            drawable?.let {
                if (it is BitmapDrawable) {
                    it.bitmap?.let {
                        if (it.isRecycled) {
                            //KLoggerUtils.e("KPhotoView位图已经释放")
                            //fixme 亲测能够解决图片异常释放问题。
                            return//图片已经释放了，就不要继续执行了。会报错的。
                        }
                    }
                }
            }
            super.draw(canvas)
            //画圆角
            drawRadius(canvas, this)
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    /**
     * fixme 设置GIF动态图片;只能加载gif动态图片，静态图片无法加载。
     * @param path 本地图片路径，网络url路径也支持。
     * @param overrideWidth 宽度，一般为480
     * @param overrideHeight 高度，一般为800
     */
    fun setGif(path: String?, overrideWidth: Int, overrideHeight: Int) {
        KGlideUtils.setGif(path, overrideWidth, overrideHeight, this)
    }

    fun setGif(resID: Int?, overrideWidth: Int, overrideHeight: Int) {
        KGlideUtils.setGif(resID, overrideWidth, overrideHeight, this)
    }

    //设置图片(支持本地，也支持网络url图片。);fixme 静态图片和gif动态（显示第一帧图片）图片都能显示。
    fun setImage(path: String?, overrideWidth: Int, overrideHeight: Int) {
        KGlideUtils.setImage(path, overrideWidth, overrideHeight, this)
    }

    fun setImage(resID: Int?, overrideWidth: Int, overrideHeight: Int) {
        KGlideUtils.setImage(resID, overrideWidth, overrideHeight, this)
    }

    //fixme 不可用状态
    var radius_notEnable: KRadiusEntity? = null

    fun radius_notEnable(block: KRadiusEntity.() -> Unit): KImageView {
        if (radius_notEnable == null) {
            radius_notEnable = gtmRadius().copy()//整个属性全部复制过来。
        }
        block(radius_notEnable!!)
        invalidate()
        //requestLayout()
        return this
    }

    //按下
    var radius_press: KRadiusEntity? = null

    fun radius_press(block: KRadiusEntity.() -> Unit): KImageView {
        if (radius_press == null) {
            radius_press = gtmRadius().copy()//整个属性全部复制过来。
        }
        block(radius_press!!)
        invalidate()
        //requestLayout()
        return this
    }

    //鼠标悬浮
    var radius_hover: KRadiusEntity? = null

    fun radius_hover(block: KRadiusEntity.() -> Unit): KImageView {
        if (radius_hover == null) {
            radius_hover = gtmRadius().copy()//整个属性全部复制过来。
        }
        block(radius_hover!!)
        invalidate()
        //requestLayout()
        return this
    }

    //聚焦
    var radius_focuse: KRadiusEntity? = null

    fun radius_focuse(block: KRadiusEntity.() -> Unit): KImageView {
        if (radius_focuse == null) {
            radius_focuse = gtmRadius().copy()//整个属性全部复制过来。
        }
        block(radius_focuse!!)
        invalidate()
        //requestLayout()
        return this
    }

    //选中
    var radius_selected: KRadiusEntity? = null

    fun radius_selected(block: KRadiusEntity.() -> Unit): KImageView {
        if (radius_selected == null) {
            radius_selected = gtmRadius().copy()//整个属性全部复制过来。
        }
        block(radius_selected!!)
        invalidate()
        //requestLayout()
        return this
    }

    //fixme 正常状态（先写正常样式，再写其他状态的样式，因为其他状态的样式初始值是复制正常状态的样式的。）
    var radius: KRadiusEntity? = null

    fun gtmRadius(): KRadiusEntity {
        if (radius == null) {
            radius = KRadiusEntity()
        }
        return radius!!
    }

    fun radius(block: KRadiusEntity.() -> Unit): KImageView {
        block(gtmRadius())
        invalidate()
        return this
    }

    var currentRadius: KRadiusEntity? = null

    var mPaint = Paint()

    //fixme 画背景
    fun drawBg(canvas: Canvas?, view: View) {
        if (canvas == null) {
            return
        }
        var paint = KBaseView.resetPaint(mPaint)
        view?.apply {
            var w = view.width
            var h = view.height
            var scrollX = view.scrollX
            var scrollY = view.scrollY
            if (radius != null) {
                currentRadius = null
                if (isPressed && radius_press != null) {
                    //按下
                    currentRadius = radius_press
                } else if (isHovered && radius_hover != null) {
                    //鼠标悬浮
                    currentRadius = radius_hover
                } else if (isFocused && radius_focuse != null) {
                    //聚焦
                    currentRadius = radius_focuse
                } else if (isSelected && radius_selected != null) {
                    //选中
                    currentRadius = radius_selected
                }
                //不可用，优先级最高
                if (!isEnabled && radius_notEnable != null) {
                    currentRadius = radius_notEnable
                }
                //正常
                if (currentRadius == null) {
                    currentRadius = radius
                }
                currentRadius?.let {
                    //画背景
                    var isDrawColor = false//是否画背景色
                    if (it.bg_color != Color.TRANSPARENT) {
                        paint.color = it.bg_color
                        isDrawColor = true
                    }
                    var left = scrollX + paint.strokeWidth / 2 + it.leftMargin
                    var top = scrollY.toFloat() + paint.strokeWidth / 2 + it.topMargin
                    //KLoggerUtils.e("scrollY:\t"+scrollY+"\tcenterY:\t"+centerY+"\th / 2:\t"+(h / 2.0f)+"\th:\t"+h)
                    var right = scrollX.toFloat() + w.toFloat() - it.rightMargin
                    var bottom = scrollY.toFloat() + h - it.bottomMargin

                    //KLoggerUtils.e("left:\t"+left+"\ttop:\t"+top+"\tright:\t"+right+"\tbottom:\t"+bottom)
                    if (it.bgVerticalColors != null) {
                        var shader: LinearGradient? = null
                        if (!it.isBgGradient) {
                            //垂直不渐变
                            if (it.bgVerticalColors!!.size == 1) {
                                //fixme 颜色渐变数组必须大于等于2
                                var bgVerticalColors = IntArray(2)
                                bgVerticalColors[0] = it.bgVerticalColors!![0]
                                bgVerticalColors[1] = it.bgVerticalColors!![0]
                                shader = K0Widget.getNotLinearGradient(top, bottom, bgVerticalColors!!, true, scrollY)
                            } else {
                                shader = K0Widget.getNotLinearGradient(top, bottom, it.bgVerticalColors!!, true, scrollY)
                            }
                        }
                        //垂直渐变，优先级高于水平(渐变颜色值数组必须大于等于2，不然异常)
                        if (shader == null) {
                            if (it.bgVerticalColors!!.size == 1) {
                                var bgVerticalColors = IntArray(2)
                                bgVerticalColors[0] = it.bgVerticalColors!![0]
                                bgVerticalColors[1] = it.bgVerticalColors!![0]
                                shader = LinearGradient(0f, top, 0f, bottom, bgVerticalColors, null, Shader.TileMode.MIRROR)
                            } else {
                                shader = LinearGradient(0f, top, 0f, bottom, it.bgVerticalColors!!, null, Shader.TileMode.MIRROR)
                            }
                        }
                        paint.setShader(shader)
                        isDrawColor = true
                    } else if (it.bgHorizontalColors != null) {
                        var shader: LinearGradient? = null
                        if (!it.isBgGradient) {
                            //水平不渐变
                            if (it.bgHorizontalColors!!.size == 1) {
                                var bgHorizontalColors = IntArray(2)
                                bgHorizontalColors[0] = it.bgHorizontalColors!![0]
                                bgHorizontalColors[1] = it.bgHorizontalColors!![0]
                                shader = K0Widget.getNotLinearGradient(left, right, bgHorizontalColors!!, false, scrollY)
                            } else {
                                shader = K0Widget.getNotLinearGradient(left, right, it.bgHorizontalColors!!, false, scrollY)
                            }
                        }
                        //水平渐变
                        if (shader == null) {
                            if (it.bgHorizontalColors!!.size == 1) {
                                var bgHorizontalColors = IntArray(2)
                                bgHorizontalColors[0] = it.bgHorizontalColors!![0]
                                bgHorizontalColors[1] = it.bgHorizontalColors!![0]
                                shader = LinearGradient(left, 0f, right, 0f, bgHorizontalColors, null, Shader.TileMode.MIRROR)
                            } else {
                                shader = LinearGradient(left, 0f, right, 0f, it.bgHorizontalColors!!, null, Shader.TileMode.MIRROR)
                            }
                        }
                        paint.setShader(shader)
                        isDrawColor = true
                    }
                    if (it.left_top < 0) {
                        it.left_top = it.all_radius
                    }
                    if (it.left_bottom < 0) {
                        it.left_bottom = it.all_radius
                    }
                    if (it.right_top < 0) {
                        it.right_top = it.all_radius
                    }
                    if (it.right_bottom < 0) {
                        it.right_bottom = it.all_radius
                    }
                    if (Build.VERSION.SDK_INT <= 17) {
                        var h2 = h.toFloat()
                        if (w < h) {
                            h2 = w.toFloat()//取小的那一边
                        }
                        h2 = h2 / 2
                        if (it.left_top > h2) {
                            it.left_top = h2
                        }
                        if (it.right_top > h2) {
                            it.right_top = h2
                        }
                        if (it.right_bottom > h2) {
                            it.right_bottom = h2
                        }
                        if (it.left_bottom > h2) {
                            it.left_bottom = h2
                        }
                    }
                    if (isDrawColor) {
                        // fixme 矩形弧度,防止Toat背景色没有圆角效果。所以直接画圆角背景
                        val radian = floatArrayOf(it.left_top!!, it.left_top!!, it.right_top, it.right_top, it.right_bottom, it.right_bottom, it.left_bottom, it.left_bottom)
                        //fixme  画圆角矩形背景
                        var rectF = RectF(left, top, right, bottom)
                        var path = Path()
                        path.addRoundRect(rectF, radian, Path.Direction.CW)
                        canvas?.drawPath(path, paint)
                    }
                }
            }
        }
    }

    //fixme 画圆角
    fun drawRadius(canvas: Canvas?, view: View) {
        currentRadius?.apply {
            drawRadius(canvas, this, view)
        }
    }

    private var kradius: KRadiusUtils? = KRadiusUtils()
    private var radius_phase: Float = 0F

    //画边框，圆角
    fun drawRadius(canvas: Canvas?, model: KRadiusEntity, view: View) {
        if (canvas == null) {
            return
        }
        view?.apply {
            model.let {
                //画圆角
                kradius?.apply {
                    x = 0f
                    y = 0f
                    w = view.width
                    h = view.height
                    leftMargin = it.leftMargin
                    topMargin = it.topMargin
                    rightMargin = it.rightMargin
                    bottomMargin = it.bottomMargin
                    view?.layoutParams?.let {
                        if (w < it.width) {
                            w = it.width
                        }
                        if (h < it.height) {
                            h = it.height
                        }
                    }
                    isDST_IN = it.isPorterDuffXfermode//fixme 取下面的交集
                    all_radius = it.all_radius
                    left_top = it.left_top
                    left_bottom = it.left_bottom
                    right_top = it.right_top
                    right_bottom = it.right_bottom
                    strokeWidth = it.strokeWidth
                    strokeColor = it.strokeColor
                    //支持虚线边框
                    dashWidth = it.dashWidth
                    dashGap = it.dashGap
                    strokeGradientColors = it.strokeHorizontalColors
                    strokeGradientOritation = ORIENTATION_HORIZONTAL
                    if (it.strokeVerticalColors != null) {
                        strokeGradientColors = it.strokeVerticalColors
                        strokeGradientOritation = ORIENTATION_VERTICAL
                    }
                    isStrokeGradient = it.isStrokeGradient
                    drawRadius(canvas, radius_phase, view.scrollX, view.scrollY)
                    //控制虚线流动性
                    if (it.isdashFlow && (dashWidth > 0 && dashGap > 0)) {
                        if (it.dashSpeed > 0) {
                            if (radius_phase >= Float.MAX_VALUE - it.dashSpeed) {
                                radius_phase = 0f
                            }
                        } else {
                            if (radius_phase >= Float.MIN_VALUE - it.dashSpeed) {
                                radius_phase = 0f
                            }
                        }
                        radius_phase += it.dashSpeed
                        invalidate()
                    }
                }
            }
        }

    }

}